Public Class WorkHoursControl
    Event ExceptionsChanged(ByVal Sender As Object, ByVal e As System.EventArgs)
    Protected Sub OnExceptionsChanged()
        RaiseEvent ExceptionsChanged(Me, EventArgs.Empty)

    End Sub


    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        'Me.Dock = DockStyle.Fill
        dtExceptionStart.DateTime = Now.Date.Date


    End Sub
    Private SettingsExceptions As New List(Of WorkHoursSettings.HourSettingException)


    Private _CaptionColor As Color
    Public Property CaptionColor() As Color
        Get
            Return _CaptionColor
        End Get
        Set(ByVal value As Color)
            _CaptionColor = value
            SetColor()

        End Set
    End Property
    Private Sub SetColor()

        For Each lbl As DevExpress.XtraEditors.LabelControl In From lb In (Me.TableLayoutPanel1.Controls).OfType(Of DevExpress.XtraEditors.LabelControl)()

            lbl.ForeColor = Me.CaptionColor
        Next

        For Each lbl As DevExpress.XtraEditors.LabelControl In From lb In (pnlExceptions.Controls).OfType(Of DevExpress.XtraEditors.LabelControl)()

            lbl.ForeColor = Me.CaptionColor
        Next


    End Sub


    Private _HourSettings As WorkHoursSettings
    <System.ComponentModel.Browsable(False), _
    System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)> _
    Public Property HourSettings() As WorkHoursSettings
        Get
            Return _HourSettings
        End Get
        Set(ByVal value As WorkHoursSettings)
            _HourSettings = value
            LoadSettings(value)
            LoadWorkdays()
        End Set
    End Property
    Private Function CreateDate(ByVal Hour As Integer, ByVal Minute As Integer) As Date
        Return New Date(Now.Year, Now.Month, Now.Day, Hour, Minute, 0)

    End Function
    Private IsLoading As Boolean
    Private Sub LoadSettings(ByVal Settings As WorkHoursSettings)
        IsLoading = True
        tmSundayStart.Time = CreateDate(Settings.SundayStartHour, Settings.SundayStartMinute)
        tmSundayEnd.Time = CreateDate(Settings.SundayEndHour, Settings.SundayEndMinute)

        tmMondayStart.Time = CreateDate(Settings.MondayStartHour, Settings.MondayStartMinute)
        tmMondayEnd.Time = CreateDate(Settings.MondayEndHour, Settings.MondayEndMinute)

        tmTuesdayStart.Time = CreateDate(Settings.TuesdayStartHour, Settings.TuesdayStartMinute)
        tmTuesdayEnd.Time = CreateDate(Settings.TuesdayEndHour, Settings.TuesdayEndMinute)

        tmWednesdayStart.Time = CreateDate(Settings.WednesdayStartHour, Settings.WednesdayStartMinute)
        tmWednesdayEnd.Time = CreateDate(Settings.WednesdayEndHour, Settings.WednesdayEndMinute)

        tmThursdayStart.Time = CreateDate(Settings.ThursdayStartHour, Settings.ThursdayStartMinute)
        tmThursdayEnd.Time = CreateDate(Settings.ThursdayEndHour, Settings.ThursdayEndMinute)

        tmFridayStart.Time = CreateDate(Settings.FridayStartHour, Settings.FridayStartMinute)
        tmFridayEnd.Time = CreateDate(Settings.FridayEndHour, Settings.FridayEndMinute)

        tmSaturdayStart.Time = CreateDate(Settings.SaturdayStartHour, Settings.SaturdayStartMinute)
        tmSaturdayEnd.Time = CreateDate(Settings.SaturdayEndHour, Settings.SaturdayEndMinute)
        SettingsExceptions = Settings.SettingsExceptions
        BuildExceptionItems()

        IsLoading = False

    End Sub
    Private Sub CreateSettings()

        Dim settings As New WorkHoursSettings

        settings.SundayStartHour = tmSundayStart.Time.Hour
        settings.SundayStartMinute = tmSundayStart.Time.Minute

        settings.MondayStartHour = tmMondayStart.Time.Hour
        settings.MondayStartMinute = tmMondayStart.Time.Minute

        settings.TuesdayStartHour = tmTuesdayStart.Time.Hour
        settings.TuesdayStartMinute = tmTuesdayStart.Time.Minute

        settings.WednesdayStartHour = tmWednesdayStart.Time.Hour
        settings.WednesdayStartMinute = tmWednesdayStart.Time.Minute

        settings.ThursdayStartHour = tmThursdayStart.Time.Hour
        settings.ThursdayStartMinute = tmThursdayStart.Time.Minute

        settings.FridayStartHour = tmFridayStart.Time.Hour
        settings.FridayStartMinute = tmFridayStart.Time.Minute

        settings.SaturdayStartHour = tmSaturdayStart.Time.Hour
        settings.SaturdayStartMinute = tmSaturdayStart.Time.Minute

        settings.SundayEndHour = tmSundayEnd.Time.Hour
        settings.SundayEndMinute = tmSundayEnd.Time.Minute

        settings.MondayEndHour = tmMondayEnd.Time.Hour
        settings.MondayEndMinute = tmMondayEnd.Time.Minute

        settings.TuesdayEndHour = tmTuesdayEnd.Time.Hour
        settings.TuesdayEndMinute = tmTuesdayEnd.Time.Minute

        settings.WednesdayEndHour = tmWednesdayEnd.Time.Hour
        settings.WednesdayEndMinute = tmWednesdayEnd.Time.Minute

        settings.ThursdayEndHour = tmThursdayEnd.Time.Hour
        settings.ThursdayEndMinute = tmThursdayEnd.Time.Minute

        settings.FridayEndHour = tmFridayEnd.Time.Hour
        settings.FridayEndMinute = tmFridayEnd.Time.Minute

        settings.SaturdayEndHour = tmSaturdayEnd.Time.Hour
        settings.SaturdayEndMinute = tmSaturdayEnd.Time.Minute

        Dim days As WorkHoursSettings.WorkingDays
        days = WorkHoursSettings.WorkingDays.None

        If chkSunday.Checked Then days = days Or WorkHoursSettings.WorkingDays.Sunday
        If chkMonday.Checked Then days = days Or WorkHoursSettings.WorkingDays.Monday
        If chkTuesday.Checked Then days = days Or WorkHoursSettings.WorkingDays.Tuesday
        If chkWednesday.Checked Then days = days Or WorkHoursSettings.WorkingDays.Wednesday
        If chkThursday.Checked Then days = days Or WorkHoursSettings.WorkingDays.Thursday
        If chkFriday.Checked Then days = days Or WorkHoursSettings.WorkingDays.Friday
        If chkSaturday.Checked Then days = days Or WorkHoursSettings.WorkingDays.Saturday
        settings.DaysToWork = days
        settings.SettingsExceptions = SettingsExceptions

        IsLoading = True

        Me.HourSettings = settings
        IsLoading = False
    End Sub

    Private Sub tm_EditValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmSundayStart.EditValueChanged, tmWednesdayStart.EditValueChanged, tmWednesdayEnd.EditValueChanged, tmTuesdayStart.EditValueChanged, tmTuesdayEnd.EditValueChanged, tmThursdayStart.EditValueChanged, tmThursdayEnd.EditValueChanged, tmSundayEnd.EditValueChanged, tmSaturdayStart.EditValueChanged, tmSaturdayEnd.EditValueChanged, tmMondayStart.EditValueChanged, tmMondayEnd.EditValueChanged, tmFridayStart.EditValueChanged, tmFridayEnd.EditValueChanged
        If Not IsLoading Then CreateSettings()
    End Sub
    Private Sub LoadWorkdays()
        IsLoading = True
        If HourSettings.DaysToWork = WorkHoursSettings.WorkingDays.None Then
            chkSunday.Checked = False
            chkMonday.Checked = False
            chkTuesday.Checked = False
            chkWednesday.Checked = False
            chkThursday.Checked = False
            chkFriday.Checked = False
            chkSaturday.Checked = False
            IsLoading = False
            Return
        End If

        If HourSettings.DaysToWork = WorkHoursSettings.WorkingDays.Everyday Then
            chkSunday.Checked = True
            chkMonday.Checked = True
            chkTuesday.Checked = True
            chkWednesday.Checked = True
            chkThursday.Checked = True
            chkFriday.Checked = True
            chkSaturday.Checked = True
            IsLoading = False
            Return
        End If
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Sunday Then
            chkSunday.Checked = True
        Else
            chkSunday.Checked = False
        End If
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Monday Then
            chkMonday.Checked = True
        Else
            chkMonday.Checked = False
        End If
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Tuesday Then
            chkTuesday.Checked = True
        Else
            chkTuesday.Checked = False
        End If

        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Wednesday Then
            chkWednesday.Checked = True
        Else
            chkWednesday.Checked = False
        End If
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Thursday Then
            chkThursday.Checked = True
        Else
            chkThursday.Checked = False
        End If
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Friday Then
            chkFriday.Checked = True
        Else
            chkFriday.Checked = False
        End If
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Saturday Then
            chkSaturday.Checked = True
        Else
            chkSaturday.Checked = False
        End If




        IsLoading = False
    End Sub
    Private Sub chk_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkSunday.CheckedChanged, chkWednesday.CheckedChanged, chkTuesday.CheckedChanged, chkThursday.CheckedChanged, chkSaturday.CheckedChanged, chkMonday.CheckedChanged, chkFriday.CheckedChanged
        If Not IsLoading Then CreateSettings()
    End Sub

    Private Sub BuildExceptionItems(Optional ByVal Selected As List(Of WorkHoursSettings.HourSettingException) = Nothing)
        lvExceptions.BeginUpdate()
        lvExceptions.Items.Clear()
        For Each exc As WorkHoursSettings.HourSettingException In From ex In SettingsExceptions Order By ex.ExceptionDate
            Dim li As New ListViewItem(exc.ExceptionDate.ToShortDateString)
            li.SubItems.Add(exc.ExceptionStart.ToShortTimeString)
            li.SubItems.Add(exc.ExceptionEnd.ToShortTimeString)
            li.Tag = exc
            lvExceptions.Items.Add(li)
            If Selected IsNot Nothing AndAlso Selected.Contains(exc) Then li.Selected = True

        Next
        lvExceptions.EndUpdate()
        If lvExceptions.Items.Count = 0 Then btnRemoveException.Enabled = False
    End Sub
    Private Sub btnAddException_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddException.Click
        If tmExceptionStart.Time > tmExceptionEnd.Time Then
            dxEp.SetError(tmExceptionStart, "Start time must be an earlier time than the end time.")
            Return
        Else
            dxEp.SetError(tmExceptionStart, "")
            If dtExceptionEnd.EditValue IsNot Nothing Then
                Dim st As Date = dtExceptionStart.DateTime.Date
                Dim en As Date = dtExceptionEnd.DateTime.Date
                If en < st Then
                    dxEp.SetError(dtExceptionEnd, "End date must be later than start date.")
                Else
                    dxEp.SetError(dtExceptionEnd, "")


                End If
            Else
                dxEp.SetError(dtExceptionEnd, "")
            End If
        End If
        Dim sDate As Date = dtExceptionStart.DateTime.Date
        Dim eDate As Date = sDate
        Dim exItems As New List(Of WorkHoursSettings.HourSettingException)
        If dtExceptionEnd.EditValue IsNot Nothing Then eDate = dtExceptionEnd.DateTime.Date
        While sDate <= eDate
            Dim exc As New WorkHoursSettings.HourSettingException With {.ExceptionStart = tmExceptionStart.Time,
                                                                        .ExceptionEnd = tmExceptionEnd.Time, .ExceptionDate = sDate}
            For Each extmp As WorkHoursSettings.HourSettingException In (From ex In SettingsExceptions Where ex.ExceptionDate = exc.ExceptionDate).ToArray

                SettingsExceptions.Remove(extmp)
            Next

            exItems.Add(exc)
            SettingsExceptions.Add(exc)



            sDate = sDate.AddDays(1)
        End While

        BuildExceptionItems(exItems)

        OnExceptionsChanged()


    End Sub
    Private Sub btnRemoveException_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRemoveException.Click
        If lvExceptions.SelectedIndices.Count = 0 Then Return
        For x As Integer = 0 To lvExceptions.SelectedItems.Count - 1
            Dim exc As WorkHoursSettings.HourSettingException = lvExceptions.SelectedItems(x).Tag
            SettingsExceptions.Remove(exc)
        Next

        BuildExceptionItems()
        OnExceptionsChanged()

    End Sub
    Private Sub dtException_DateTimeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtExceptionStart.DateTimeChanged, dtExceptionEnd.DateTimeChanged
        Dim dt As Date = dtExceptionStart.DateTime.Date

        tmExceptionEnd.Time = New Date(dt.Year, dt.Month, dt.Day, tmExceptionEnd.Time.Hour, tmExceptionEnd.Time.Minute, tmExceptionEnd.Time.Second)
        tmExceptionStart.Time = New Date(dt.Year, dt.Month, dt.Day, tmExceptionStart.Time.Hour, tmExceptionStart.Time.Minute, tmExceptionStart.Time.Second)

    End Sub

    Private Sub lvExceptions_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvExceptions.SelectedIndexChanged
        If lvExceptions.SelectedIndices.Count = 0 Then
            btnRemoveException.Enabled = False
        Else
            btnRemoveException.Enabled = True
        End If
    End Sub


End Class
<Serializable()> _
Public Class WorkHoursSettings
    <Flags()> _
    Public Enum WorkingDays
        Everyday = 254
        None = 0
        Sunday = 2
        Monday = 4
        Tuesday = 8
        Wednesday = 16
        Thursday = 32
        Friday = 64
        Saturday = 128

    End Enum
    Public Function GetDayTimeRange(day As Integer) As Tuple(Of TimeSpan, TimeSpan)
        If day > 6 Then Throw New ArgumentOutOfRangeException("day", "Day must be between 0(Sunday) and 6(Saturday).")
        Select Case day
            Case 0
                Return New Tuple(Of TimeSpan, TimeSpan) _
                                (
                                New TimeSpan(Me.SundayStartHour, Me.SundayStartMinute, 0), New TimeSpan(SundayEndHour, SundayEndHour, SundayEndMinute, 0)
                                )
            Case 1
                Return New Tuple(Of TimeSpan, TimeSpan) _
                               (
                               New TimeSpan(Me.MondayStartHour, Me.MondayStartMinute, 0), New TimeSpan(MondayEndHour, MondayEndHour, MondayEndMinute, 0)
                               )
            Case 2
                Return New Tuple(Of TimeSpan, TimeSpan) _
                                (
                                New TimeSpan(Me.TuesdayStartHour, Me.TuesdayStartMinute, 0), New TimeSpan(TuesdayEndHour, TuesdayEndHour, TuesdayEndMinute, 0)
                                )
            Case 3
                Return New Tuple(Of TimeSpan, TimeSpan) _
               (
               New TimeSpan(Me.WednesdayStartHour, Me.WednesdayStartMinute, 0), New TimeSpan(WednesdayEndHour, WednesdayEndHour, WednesdayEndMinute, 0)
               )
            Case 4
                Return New Tuple(Of TimeSpan, TimeSpan) _
               (
               New TimeSpan(Me.ThursdayStartHour, Me.ThursdayStartMinute, 0), New TimeSpan(ThursdayEndHour, ThursdayEndHour, ThursdayEndMinute, 0)
               )
            Case 5
                Return New Tuple(Of TimeSpan, TimeSpan) _
               (
               New TimeSpan(Me.FridayStartHour, Me.FridayStartMinute, 0), New TimeSpan(FridayEndHour, FridayEndHour, FridayEndMinute, 0)
               )
            Case 6
                Return New Tuple(Of TimeSpan, TimeSpan) _
               (
               New TimeSpan(Me.SaturdayStartHour, Me.SaturdayStartMinute, 0), New TimeSpan(SaturdayEndHour, SaturdayEndHour, SaturdayEndMinute, 0)
               )
            Case Else
                Return New Tuple(Of TimeSpan, TimeSpan)(TimeSpan.Zero, TimeSpan.Zero)
        End Select

    End Function
    ''' <summary>
    ''' Returns a <see cref="DevExpress.XtraScheduler.TimeInterval">TimeInterval</see> that is the valid work start and end for the specified date.
    ''' </summary>
    ''' <param name="day">The selected date to query.</param>
    ''' <param name="SkipWorkExceptions">Used to selectively ignore the exceptions of the work days added by the user.  If true the exceptions are ignored.</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DayToWorkingTimeInterval(ByVal day As Date, Optional ByVal SkipWorkExceptions As Boolean = False) As DevExpress.XtraScheduler.TimeInterval
        Dim ti As DevExpress.XtraScheduler.TimeInterval = Nothing
        Select Case day.DayOfWeek
            Case DayOfWeek.Sunday
                Dim tod As New DevExpress.XtraScheduler.TimeOfDayInterval(New TimeSpan(SundayStartHour, SundayStartMinute, 0), New TimeSpan(SundayEndHour, SundayEndMinute, 0))
                ti = tod.ToTimeInterval(day.Date)
            Case DayOfWeek.Monday
                Dim tod As New DevExpress.XtraScheduler.TimeOfDayInterval(New TimeSpan(MondayStartHour, MondayStartMinute, 0), New TimeSpan(MondayEndHour, MondayEndMinute, 0))
                ti = tod.ToTimeInterval(day.Date)
            Case DayOfWeek.Tuesday
                Dim tod As New DevExpress.XtraScheduler.TimeOfDayInterval(New TimeSpan(TuesdayStartHour, TuesdayStartMinute, 0), New TimeSpan(TuesdayEndHour, TuesdayEndMinute, 0))
                ti = tod.ToTimeInterval(day.Date)
            Case DayOfWeek.Wednesday
                Dim tod As New DevExpress.XtraScheduler.TimeOfDayInterval(New TimeSpan(WednesdayStartHour, WednesdayStartMinute, 0), New TimeSpan(WednesdayEndHour, WednesdayEndMinute, 0))
                ti = tod.ToTimeInterval(day.Date)
            Case DayOfWeek.Thursday
                Dim tod As New DevExpress.XtraScheduler.TimeOfDayInterval(New TimeSpan(ThursdayStartHour, ThursdayStartMinute, 0), New TimeSpan(ThursdayEndHour, ThursdayEndMinute, 0))
                ti = tod.ToTimeInterval(day.Date)
            Case DayOfWeek.Friday
                Dim tod As New DevExpress.XtraScheduler.TimeOfDayInterval(New TimeSpan(FridayStartHour, FridayStartMinute, 0), New TimeSpan(FridayEndHour, FridayEndMinute, 0))
                ti = tod.ToTimeInterval(day.Date)
            Case DayOfWeek.Saturday
                Dim tod As New DevExpress.XtraScheduler.TimeOfDayInterval(New TimeSpan(SaturdayStartHour, SaturdayStartMinute, 0), New TimeSpan(SaturdayEndHour, SaturdayEndMinute, 0))
                ti = tod.ToTimeInterval(day.Date)

        End Select
        If Not SkipWorkExceptions Then
            Dim exc As HourSettingException = (From ex In SettingsExceptions Where ex.ExceptionDate.Date = day.Date).FirstOrDefault
            If exc IsNot Nothing Then ti = exc.ToTimeOfDayInterval.ToTimeInterval(day.Date)
        End If

        Return ti

    End Function
    Public Function IsWorkingDay(ByVal Day As Date) As Boolean
        Dim Answer As Boolean
        Select Case Day.DayOfWeek
            Case DayOfWeek.Sunday
                Answer = Me.DaysToWork And WorkingDays.Sunday
            Case DayOfWeek.Monday
                Answer = Me.DaysToWork And WorkingDays.Monday
            Case DayOfWeek.Tuesday
                Answer = Me.DaysToWork And WorkingDays.Tuesday
            Case DayOfWeek.Wednesday
                Answer = Me.DaysToWork And WorkingDays.Wednesday
            Case DayOfWeek.Thursday
                Answer = Me.DaysToWork And WorkingDays.Thursday
            Case DayOfWeek.Friday
                Answer = Me.DaysToWork And WorkingDays.Friday
            Case DayOfWeek.Saturday
                Answer = Me.DaysToWork And WorkingDays.Saturday
        End Select
        If Answer Then
            If Day < Me.SemesterStart OrElse Day > Me.SemesterEnd Then Answer = False
        End If
        Return Answer
    End Function
    Private Function TimeSpanFromSetting(ByVal hour As Integer, ByVal Minute As Integer)
        Return New TimeSpan(hour, Minute, 0)
    End Function
    Private Function LargestTime(ByVal ts1 As TimeSpan, ByVal ts2 As TimeSpan)
        If ts1 > ts2 Then Return ts1
        Return ts2

    End Function
    Private Function SmallestTime(ByVal ts1 As TimeSpan, ByVal ts2 As TimeSpan)
        If ts1 < ts2 Then Return ts1
        Return ts2

    End Function

    Public Function getMinStartTime(day As DayOfWeek) As DateTime
        Dim dt As Date = Me.DayToWorkingTimeInterval(GetNextDay(day, Me.SemesterStart), True).Start
        Return New Date(Me.SemesterStart.Year, Me.SemesterStart.Month, Me.SemesterStart.Day, dt.Hour, dt.Minute, dt.Second)

    End Function
    Public Function getMaxEndTime(day As DayOfWeek) As DateTime
        Dim dt As Date = Me.DayToWorkingTimeInterval(GetLastDay(day, Me._SemesterEnd), True).End
        Return New Date(Me.SemesterEnd.Year, Me.SemesterEnd.Month, Me.SemesterEnd.Day, dt.Hour, dt.Minute, dt.Second)


    End Function
    Public Function GetLargestWorkingHour() As Integer
        Dim max As New TimeSpan(0, 0, 0)

        If Me.DaysToWork And WorkingDays.Sunday Then max = LargestTime(max, TimeSpanFromSetting(SundayEndHour, SundayEndMinute))
        If Me.DaysToWork And WorkingDays.Monday Then max = LargestTime(max, TimeSpanFromSetting(MondayEndHour, MondayEndMinute))
        If Me.DaysToWork And WorkingDays.Tuesday Then max = LargestTime(max, TimeSpanFromSetting(TuesdayEndHour, TuesdayEndMinute))
        If Me.DaysToWork And WorkingDays.Wednesday Then max = LargestTime(max, TimeSpanFromSetting(WednesdayEndHour, WednesdayEndMinute))
        If Me.DaysToWork And WorkingDays.Thursday Then max = LargestTime(max, TimeSpanFromSetting(ThursdayEndHour, ThursdayEndMinute))
        If Me.DaysToWork And WorkingDays.Friday Then max = LargestTime(max, TimeSpanFromSetting(FridayEndHour, FridayEndMinute))
        If Me.DaysToWork And WorkingDays.Saturday Then max = LargestTime(max, TimeSpanFromSetting(SaturdayEndHour, SaturdayEndMinute))
        Return max.Hours
    End Function

    Public Function GetSmallestWorkingHour() As Integer
        Dim min As New TimeSpan(23, 59, 59)
        If Me.DaysToWork And WorkingDays.Sunday Then min = SmallestTime(min, TimeSpanFromSetting(SundayStartHour, SundayStartMinute))
        If Me.DaysToWork And WorkingDays.Monday Then min = SmallestTime(min, TimeSpanFromSetting(MondayStartHour, MondayStartMinute))
        If Me.DaysToWork And WorkingDays.Tuesday Then min = SmallestTime(min, TimeSpanFromSetting(TuesdayStartHour, TuesdayStartMinute))
        If Me.DaysToWork And WorkingDays.Wednesday Then min = SmallestTime(min, TimeSpanFromSetting(WednesdayStartHour, WednesdayStartMinute))
        If Me.DaysToWork And WorkingDays.Thursday Then min = SmallestTime(min, TimeSpanFromSetting(ThursdayStartHour, ThursdayStartMinute))
        If Me.DaysToWork And WorkingDays.Friday Then min = SmallestTime(min, TimeSpanFromSetting(FridayStartHour, FridayStartMinute))
        If Me.DaysToWork And WorkingDays.Saturday Then min = SmallestTime(min, TimeSpanFromSetting(SaturdayStartHour, SaturdayStartMinute))
        Return min.Hours
    End Function
    Public Function GetLargestWorkingMinute() As Integer
        Dim max As New TimeSpan(0, 0, 0)

        If Me.DaysToWork And WorkingDays.Sunday Then max = LargestTime(max, TimeSpanFromSetting(SundayEndHour, SundayEndMinute))
        If Me.DaysToWork And WorkingDays.Monday Then max = LargestTime(max, TimeSpanFromSetting(MondayEndHour, MondayEndMinute))
        If Me.DaysToWork And WorkingDays.Tuesday Then max = LargestTime(max, TimeSpanFromSetting(TuesdayEndHour, TuesdayEndMinute))
        If Me.DaysToWork And WorkingDays.Wednesday Then max = LargestTime(max, TimeSpanFromSetting(WednesdayEndHour, WednesdayEndMinute))
        If Me.DaysToWork And WorkingDays.Thursday Then max = LargestTime(max, TimeSpanFromSetting(ThursdayEndHour, ThursdayEndMinute))
        If Me.DaysToWork And WorkingDays.Friday Then max = LargestTime(max, TimeSpanFromSetting(FridayEndHour, FridayEndMinute))
        If Me.DaysToWork And WorkingDays.Saturday Then max = LargestTime(max, TimeSpanFromSetting(SaturdayEndHour, SaturdayEndMinute))
        Return max.Minutes
    End Function

    Public Function GetSmallestWorkingMinute() As Integer
        Dim min As New TimeSpan(23, 59, 59)
        If Me.DaysToWork And WorkingDays.Sunday Then min = SmallestTime(min, TimeSpanFromSetting(SundayStartHour, SundayStartMinute))
        If Me.DaysToWork And WorkingDays.Monday Then min = SmallestTime(min, TimeSpanFromSetting(MondayStartHour, MondayStartMinute))
        If Me.DaysToWork And WorkingDays.Tuesday Then min = SmallestTime(min, TimeSpanFromSetting(TuesdayStartHour, TuesdayStartMinute))
        If Me.DaysToWork And WorkingDays.Wednesday Then min = SmallestTime(min, TimeSpanFromSetting(WednesdayStartHour, WednesdayStartMinute))
        If Me.DaysToWork And WorkingDays.Thursday Then min = SmallestTime(min, TimeSpanFromSetting(ThursdayStartHour, ThursdayStartMinute))
        If Me.DaysToWork And WorkingDays.Friday Then min = SmallestTime(min, TimeSpanFromSetting(FridayStartHour, FridayStartMinute))
        If Me.DaysToWork And WorkingDays.Saturday Then min = SmallestTime(min, TimeSpanFromSetting(SaturdayStartHour, SaturdayStartMinute))
        Return min.Minutes
    End Function


    Private _SettingsExceptions As New List(Of HourSettingException)
    <Xml.Serialization.XmlArray("Exceptions"), _
   Xml.Serialization.XmlArrayItem("Exception", GetType(HourSettingException))> _
    Public Property SettingsExceptions() As List(Of HourSettingException)
        Get
            Return _SettingsExceptions
        End Get
        Set(ByVal value As List(Of HourSettingException))
            _SettingsExceptions = value
        End Set
    End Property



    Private _DaysToWork As WorkingDays
    Public Property DaysToWork() As WorkingDays
        Get
            Return _DaysToWork
        End Get
        Set(ByVal value As WorkingDays)
            _DaysToWork = value
        End Set
    End Property


    Private _SemesterStart As Date = #5/18/2009#
    Public Property SemesterStart() As Date
        Get
            Return _SemesterStart
        End Get
        Set(ByVal value As Date)
            _SemesterStart = value
        End Set
    End Property

    Private _SemesterEnd As Date = #7/28/2009#
    Public Property SemesterEnd() As Date
        Get
            Return _SemesterEnd
        End Get
        Set(ByVal value As Date)
            value = New Date(value.Year, value.Month, value.Day, 23, 59, 0)

            _SemesterEnd = value
        End Set
    End Property



    Private _SundayStartHour As Integer = 0

    Public Property SundayStartHour() As Integer
        Get
            Return _SundayStartHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _SundayStartHour = value
        End Set
    End Property

    Private _SundayStartMinute As Integer = 0

    Public Property SundayStartMinute() As Integer
        Get
            Return _SundayStartMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _SundayStartMinute = value
        End Set
    End Property

    Private _SundayEndHour As Integer = 0

    Public Property SundayEndHour() As Integer
        Get
            Return _SundayEndHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _SundayEndHour = value
        End Set
    End Property

    Private _SundayEndMinute As Integer = 0

    Public Property SundayEndMinute() As Integer
        Get
            Return _SundayEndMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _SundayEndMinute = value
        End Set
    End Property

    Private _MondayStartHour As Integer = 7

    Public Property MondayStartHour() As Integer
        Get
            Return _MondayStartHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _MondayStartHour = value
        End Set
    End Property

    Private _MondayStartMinute As Integer = 30

    Public Property MondayStartMinute() As Integer
        Get
            Return _MondayStartMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _MondayStartMinute = value
        End Set
    End Property

    Private _MondayEndHour As Integer = 21

    Public Property MondayEndHour() As Integer
        Get
            Return _MondayEndHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _MondayEndHour = value
        End Set
    End Property

    Private _MondayEndMinute As Integer = 0

    Public Property MondayEndMinute() As Integer
        Get
            Return _MondayEndMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _MondayEndMinute = value
        End Set
    End Property

    Private _TuesdayStartHour As Integer = 7

    Public Property TuesdayStartHour() As Integer
        Get
            Return _TuesdayStartHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _TuesdayStartHour = value
        End Set
    End Property

    Private _TuesdayStartMinute As Integer = 30

    Public Property TuesdayStartMinute() As Integer
        Get
            Return _TuesdayStartMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _TuesdayStartMinute = value
        End Set
    End Property

    Private _TuesdayEndHour As Integer = 21

    Public Property TuesdayEndHour() As Integer
        Get
            Return _TuesdayEndHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _TuesdayEndHour = value
        End Set
    End Property

    Private _TuesdayEndMinute As Integer = 0

    Public Property TuesdayEndMinute() As Integer
        Get
            Return _TuesdayEndMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _TuesdayEndMinute = value
        End Set
    End Property

    Private _WednesdayStartHour As Integer = 7

    Public Property WednesdayStartHour() As Integer
        Get
            Return _WednesdayStartHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _WednesdayStartHour = value
        End Set
    End Property

    Private _WednesdayStartMinute As Integer = 30

    Public Property WednesdayStartMinute() As Integer
        Get
            Return _WednesdayStartMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _WednesdayStartMinute = value
        End Set
    End Property

    Private _WednesdayEndHour As Integer = 21

    Public Property WednesdayEndHour() As Integer
        Get
            Return _WednesdayEndHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _WednesdayEndHour = value
        End Set
    End Property

    Private _WednesdayEndMinute As Integer = 0

    Public Property WednesdayEndMinute() As Integer
        Get
            Return _WednesdayEndMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _WednesdayEndMinute = value
        End Set
    End Property

    Private _ThursdayStartHour As Integer = 7

    Public Property ThursdayStartHour() As Integer
        Get
            Return _ThursdayStartHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _ThursdayStartHour = value
        End Set
    End Property

    Private _ThursdayStartMinute As Integer = 30

    Public Property ThursdayStartMinute() As Integer
        Get
            Return _ThursdayStartMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _ThursdayStartMinute = value
        End Set
    End Property

    Private _ThursdayEndHour As Integer = 21

    Public Property ThursdayEndHour() As Integer
        Get
            Return _ThursdayEndHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _ThursdayEndHour = value
        End Set
    End Property

    Private _ThursdayEndMinute As Integer = 0

    Public Property ThursdayEndMinute() As Integer
        Get
            Return _ThursdayEndMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _ThursdayEndMinute = value
        End Set
    End Property

    Private _FridayStartHour As Integer = 7

    Public Property FridayStartHour() As Integer
        Get
            Return _FridayStartHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _FridayStartHour = value
        End Set
    End Property

    Private _FridayStartMinute As Integer = 30

    Public Property FridayStartMinute() As Integer
        Get
            Return _FridayStartMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _FridayStartMinute = value
        End Set
    End Property

    Private _FridayEndHour As Integer = 15

    Public Property FridayEndHour() As Integer
        Get
            Return _FridayEndHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _FridayEndHour = value
        End Set
    End Property

    Private _FridayEndMinute As Integer = 0

    Public Property FridayEndMinute() As Integer
        Get
            Return _FridayEndMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _FridayEndMinute = value
        End Set
    End Property


    Private _SaturdayStartHour As Integer = 9

    Public Property SaturdayStartHour() As Integer
        Get
            Return _SaturdayStartHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _SaturdayStartHour = value
        End Set
    End Property

    Private _SaturdayStartMinute As Integer = 0

    Public Property SaturdayStartMinute() As Integer
        Get
            Return _SaturdayStartMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _SaturdayStartMinute = value
        End Set
    End Property

    Private _SaturdayEndHour As Integer = 12

    Public Property SaturdayEndHour() As Integer
        Get
            Return _SaturdayEndHour
        End Get
        Set(ByVal value As Integer)
            If value <= 23 AndAlso value >= 0 Then _SaturdayEndHour = value
        End Set
    End Property

    Private _SaturdayEndMinute As Integer = 0

    Public Property SaturdayEndMinute() As Integer
        Get
            Return _SaturdayEndMinute
        End Get
        Set(ByVal value As Integer)
            If value <= 59 AndAlso value >= 0 Then _SaturdayEndMinute = value
        End Set
    End Property

    Public Sub New()
        DaysToWork = WorkingDays.Monday Or WorkingDays.Tuesday Or WorkingDays.Wednesday Or WorkingDays.Thursday Or WorkingDays.Friday

    End Sub

    Public Class HourSettingException

        Public Function ToTimeOfDayInterval() As DevExpress.XtraScheduler.TimeOfDayInterval
            Dim st, en As Date
            st = New Date(ExceptionDate.Year, ExceptionDate.Month, ExceptionDate.Day, ExceptionStart.Hour, ExceptionStart.Minute, ExceptionStart.Second)
            en = New Date(ExceptionDate.Year, ExceptionDate.Month, ExceptionDate.Day, ExceptionEnd.Hour, ExceptionEnd.Minute, ExceptionEnd.Second)
            Return New DevExpress.XtraScheduler.TimeOfDayInterval(st.TimeOfDay, en.TimeOfDay)
        End Function
        Private _ExceptionDate As Date
        Public Property ExceptionDate() As Date
            Get
                Return _ExceptionDate
            End Get
            Set(ByVal value As Date)
                _ExceptionDate = value
            End Set
        End Property


        Private _ExceptionStart As Date
        Public Property ExceptionStart() As Date
            Get
                Return _ExceptionStart
            End Get
            Set(ByVal value As Date)
                _ExceptionStart = value
            End Set
        End Property


        Private _ExceptionEnd As Date
        Public Property ExceptionEnd() As Date
            Get
                Return _ExceptionEnd
            End Get
            Set(ByVal value As Date)
                _ExceptionEnd = value
            End Set
        End Property



    End Class
End Class